/*
 * h_cc2640r2f_uart.c
 *
 *  Created on: Sep 19, 2019
 *      Author: hemingway
 */
#include "h_cc2640r2f_uart.h"
#include <ti/drivers/uart/UARTCC26XX.h>

#include "h_cc2640r2f_define.h"
#include <stdio.h>
#include <string.h>

#include "simple_peripheral_oad_offchip.h"

#define H_CC2640R2F_UART_TX_SEMAPHORE           0

#define H_CC2640R2F_UART_BaudRate               H_CC2640R2F_DEBUG_BaudRate

#define H_CC2640R2F_UARTRXMAXLENGTH             H_CC2640R2F_UART_RxLength


//unsigned char H_CC2640R2F_UARTRxBuffer[H_CC2640R2F_UARTRXMAXLENGTH];
unsigned char *H_CC2640R2F_UARTRxBuffer = NULL;
volatile unsigned short H_CC2640R2F_UARTRxBufferLength = 0U;


static UART_Handle H_CC2640R2F_UARTHandle = NULL;
#if H_CC2640R2F_UART_TX_SEMAPHORE
static SemaphoreP_Handle h_cc2640r2f_semaphoreP_handle = NULL;
#endif

static void H_CC2640R2F_UART_RxCallback(UART_Handle handle, void *buf, size_t count)
{
    H_CC2640R2F_UARTRxBufferLength = count;

    SimplePeripheral_SingleNotify();
    H_CC2640R2F_UART_RxEnable();
}

void H_CC2640R2F_UART_Deinit(void)
{
    if(H_CC2640R2F_UARTHandle)
    {
        UART_close(H_CC2640R2F_UARTHandle);
    }

}

h_cc2640r2f_uart_rslt H_CC2640R2F_UART_Init(void)
{
    UART_Params uartParams;
    UART_init();

    UART_Params_init(&uartParams);
    uartParams.baudRate  = H_CC2640R2F_UART_BaudRate;
    uartParams.writeMode = UART_MODE_BLOCKING;

    uartParams.readMode = UART_MODE_CALLBACK;

    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readCallback = H_CC2640R2F_UART_RxCallback;

    uartParams.dataLength = UART_LEN_8;
#if DEBUG_USE_SECONDCONTROLLER
    uartParams.stopBits = UART_STOP_TWO;//UART_STOP_ONE;
    uartParams.parityType = UART_PAR_EVEN;//UART_PAR_NONE;
#else
    uartParams.stopBits = UART_STOP_ONE;
        uartParams.parityType = UART_PAR_NONE;
#endif

#if H_CC2640R2F_UART_TX_SEMAPHORE
    h_cc2640r2f_semaphoreP_handle = SemaphoreP_createBinary(1);
    if (NULL == h_cc2640r2f_semaphoreP_handle)
    {
        return H_CC2640R2F_UART_Sema_Failed;
    }
#endif


    H_CC2640R2F_UARTHandle = UART_open(0, &uartParams);
    if (NULL == H_CC2640R2F_UARTHandle)
    {
        return H_CC2640R2F_UART_Open_Failed;
    }

//    /* Disable RX in case that is needed to save power */
//    UART_control(H_CC2640R2F_UARTHandle, UART_CMD_RXDISABLE, NULL);
//    UART_control(H_CC2640R2F_UARTHandle, UART_CMD_RXENABLE, NULL);


    /* RX data even not a new line mode */
    UART_control(H_CC2640R2F_UARTHandle, \
                 UARTCC26XX_RETURN_PARTIAL_ENABLE, NULL);

    return H_CC2640R2F_UART_OK;
}

h_cc2640r2f_uart_rslt H_CC2640R2F_UART_Rx_Data_Init(void)
{
    if(NULL == H_CC2640R2F_UARTRxBuffer)
    {
#if H_CC2640R2F_USE_MALLOC
        H_CC2640R2F_UARTRxBuffer = (unsigned char *)H_CC2640R2F_DEBUG_MALLOC(\
                                    sizeof(unsigned char) * H_CC2640R2F_UARTRXMAXLENGTH);
#else
        Error_Block eb;
        H_CC2640R2F_UARTRxBuffer = (unsigned char *)H_CC2640R2F_DEBUG_CALLOC(\
                                     NULL, H_CC2640R2F_UARTRXMAXLENGTH, sizeof(char), &eb);
#endif
        if(NULL == H_CC2640R2F_UARTRxBuffer)
        {
            return H_CC2640R2F_UART_malloc_Failed;
        }
    }

    return H_CC2640R2F_UART_OK;
}

void H_CC2640R2F_UART_Rx_Data_Release(void)
{
    if(NULL != H_CC2640R2F_UARTRxBuffer)
    {
#if H_CC2640R2F_USE_MALLOC
        H_CC2640R2F_DEBUG_FREE(H_CC2640R2F_UARTRxBuffer);
#else
        H_CC2640R2F_DEBUG_FREE(NULL, H_CC2640R2F_UARTRxBuffer, \
                               H_CC2640R2F_UARTRXMAXLENGTH);
#endif
        H_CC2640R2F_UARTRxBuffer = NULL;
    }

}

void H_CC2640R2F_UART_TxBuff(const unsigned char *data, \
                                unsigned short length)
{
#if H_CC2640R2F_UART_TX_SEMAPHORE
    if(SemaphoreP_pend(h_cc2640r2f_semaphoreP_handle, \
                       SemaphoreP_WAIT_FOREVER) == \
                                            SemaphoreP_OK)
    {
        if(NULL == data)
        {
            return;
        }
        UART_write(H_CC2640R2F_UARTHandle, data, length);
        SemaphoreP_post(h_cc2640r2f_semaphoreP_handle);
    }
#else
    if(NULL != H_CC2640R2F_UARTHandle) {
        UART_write(H_CC2640R2F_UARTHandle, data, length);
    }

#endif
//    UART_write(H_CC2640R2F_UARTHandle, data, length);

}

void H_CC2640R2F_UART_RxEnable(void)
{
    if(NULL == H_CC2640R2F_UARTRxBuffer)
    {
        H_CC2640R2F_UART_Rx_Data_Init();
    }

    if(NULL != H_CC2640R2F_UARTRxBuffer)
    {
        if(NULL != H_CC2640R2F_UARTHandle) {
            UART_read(H_CC2640R2F_UARTHandle, H_CC2640R2F_UARTRxBuffer, \
                                  H_CC2640R2F_UARTRXMAXLENGTH);
        }

    }
}

void H_CC2640R2F_UART_RxDisable(void)
{
    if(NULL != H_CC2640R2F_UARTHandle) {
        UART_readCancel(H_CC2640R2F_UARTHandle);
        UART_writeCancel(H_CC2640R2F_UARTHandle);
    }


//    UART_control(H_CC2640R2F_UARTHandle, \
//                 UARTCC26XX_RETURN_PARTIAL_DISABLE, NULL);
//
//    UART_control(H_CC2640R2F_UARTHandle, UART_CMD_RXDISABLE, NULL);
//    UART_control(H_CC2640R2F_UARTHandle, UART_CMD_RXENABLE, NULL);
}

